package interviewClassic150;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class AlternatingOutput {
    public static void main(String[] args) {
        ReentrantLock rLock = new ReentrantLock();
        Condition c1 = rLock.newCondition();
        Condition c2 = rLock.newCondition();
        Condition c3 = rLock.newCondition();

        Thread thread1 = new Thread(()->{
            boolean locked  = false;
            try {
                locked = rLock.tryLock(10, TimeUnit.SECONDS);
                for (int i = 0; i < 10; i++) {
                    System.out.println("a");
                    c2.signal();
                    if (i != 9) c1.await();
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            } finally {
                if (locked && rLock.isHeldByCurrentThread()) rLock.unlock();
            }
        });

        Thread thread2 = new Thread(()->{
            boolean locked  = false;
            try {
                locked = rLock.tryLock(10, TimeUnit.SECONDS);
                c2.await();
                for (int i = 0; i < 10; i++) {
                    System.out.println("b");
                    c3.signal();
                    if (i != 9) c2.await();
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            } finally {
                if (locked && rLock.isHeldByCurrentThread()) rLock.unlock();
            }
        });

        Thread thread3 = new Thread(()->{
            boolean locked  = false;
            try {
                locked = rLock.tryLock(10, TimeUnit.SECONDS);
                c3.await();
                for (int i = 0; i < 10; i++) {
                    System.out.println("c");
                    c1.signal();
                    if (i != 9) c3.await();
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            } finally {
                if (locked && rLock.isHeldByCurrentThread()) rLock.unlock();
            }
        });

        thread1.start();
        thread2.start();
        thread3.start();
    }
}
